#include<stdio.h>
#include<stdlib.h>
#include<math.h>

// 只是用来生成数据的函数
int gen_int(double x) {
    return (8.0 / 3.0) * pow(x, 3) - 14 * pow(x, 2) + (55.0 / 3.0) * x + 0.1;
}

char gen_char(double x) {
    return  -14761.0 / 3628800.0 * pow(x, 10) + (143743.0 / 725760.0) * pow(x, 9) - 498317.0 / 120960.0 * pow(x, 8) + (5785693.0 / 120960.0) * pow(x, 7) - 58723933.0 / 172800.0 * pow(x, 6) + (10524695.0 / 6912.0) * pow(x, 5) - 96792449.0 / 22680.0 * pow(x, 4) + (1293776873.0 / 181440.0) * pow(x, 3) - 159233609.0 / 25200.0 * pow(x, 2) + (2757127.0 / 1260.0) * x + 73.1;
}

// vector "模板"宏
#define use_vec(T)                                                   \
typedef struct vec_##T{                                              \
    T* data;                                                         \
    size_t len;                                                      \
    size_t cap;                                                      \
}vec_##T;                                                            \
vec_##T* new_vec_##T(size_t cap){                                    \
    vec_##T* ptr = malloc(sizeof(vec_##T));                          \
    ptr->data = malloc(sizeof(T) * cap);                             \
    ptr->len = 0;                                                    \
    ptr->cap = cap ? cap : 1;                                        \
    return ptr;                                                      \
}                                                                    \
void vec_##T##_add(vec_##T* _this, T elm){                           \
    if(_this->len + 1 > _this->cap){                                 \
        _this->cap <<= 1;                                            \
        _this->data = realloc(_this->data, sizeof(T) * _this->cap);  \
    }                                                                \
    _this->data[(_this->len)++] = elm;                               \
}                                                                    \
T* vec_##T##_at(vec_##T* _this, size_t pos){                         \
    T* ptr = NULL;                                                   \
    if(pos < _this->len) ptr = &(_this->data[pos]);                  \
    return ptr;                                                      \
}                                                                    \

// 统一的释放函数
void vec_free(void* _this){
    void** data_ptr = _this;
    free(*data_ptr);
    free(_this);
}

// 自动生成代码
use_vec(int)
use_vec(char)

int main(){

    vec_int* a = new_vec_int(0);
    for(int i = 0; i < 4; ++i){
        vec_int_add(a, gen_int(i));
        printf("%d: %d cap: %d len: %d\n", i, a->data[i], a->cap, a->len);
    }
    
    // 安全访问测试
    int* tmp = vec_int_at(a, 6);
    if(tmp == NULL) printf("nullpointer\n");
    else printf("%d\n", *tmp);
    tmp = vec_int_at(a, 3);
    if(tmp == NULL) printf("nullpointer\n");
    else printf("%d\n", *tmp);
    
    // 别的类型也可以
    vec_char* b = new_vec_char(2);
    for(int i = 0; i < 11; ++i){
        vec_char_add(b, gen_char(i));
        printf("%-2d: %c cap: %d len: %d\n", i, b->data[i], b->cap, b->len);
    }
    
    // 释放内存
    vec_free(a);
    vec_free(b);
    
    return 0;
}